#include "logindialog.h"
#include <QAction>
#include <QCryptographicHash>
#include <QIcon>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonParseError>
#include <QMessageBox>
#include <QPainter>
#include <QPainterPath>
#include "httpmanager.h"
#include "tcpmgr.h"
#include "ui_logindialog.h"
LoginDialog::LoginDialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::LoginDialog)
    , _uid(0)
    , _token("")
{
    ui->setupUi(this);
    ui->login_edt_password->setEchoMode(QLineEdit::Password);
    QAction *pass_action = new QAction(this);
    pass_action->setIcon(QIcon(":/icon/icon/unvisible.png"));
    ui->login_edt_password->addAction(pass_action, QLineEdit::ActionPosition::TrailingPosition);
    connect(pass_action, &QAction::triggered, this, [this, pass_action](bool checked) {
        Q_UNUSED(checked);
        if (ui->login_edt_password->echoMode() == QLineEdit::Password) {
            pass_action->setIcon(QIcon(":/icon/icon/visible.png"));
            ui->login_edt_password->setEchoMode(QLineEdit::Normal);
        } else {
            pass_action->setIcon(QIcon(":/icon/icon/unvisible.png"));
            ui->login_edt_password->setEchoMode(QLineEdit::Password);
        }
    });
    initHead();
    initHttpHandlers();
    connect(HttpManager::GetInstance().get(),
            &HttpManager::sig_login_mod_finish,
            this,
            &LoginDialog::slot_login_finished);
    // 连接tcp请求的信号和槽
    connect(this,
            &LoginDialog::sig_connect_tcp,
            TcpMgr::GetInstance().get(),
            &TcpMgr::slot_tcp_connect);
    // 连接tcp管理者发出连接成功信号
    connect(TcpMgr::GetInstance().get(),
            &TcpMgr::sig_con_success,
            this,
            &LoginDialog::slot_tcp_con_finish);
    // 连接tcp管理者发出的登录失败信号
    connect(TcpMgr::GetInstance().get(),
            &TcpMgr::sig_login_failed,
            this,
            &LoginDialog::slot_login_failed);
}

LoginDialog::~LoginDialog()
{
    qDebug() << "LoginDialog析构\n";
    delete ui;
}

void LoginDialog::on_btn_signup_clicked()
{
    emit sigSwitchRegister();
}
// 忘记密码
void LoginDialog::on_btn_froget_clicked()
{
    emit sigSwitchForget();
}

void LoginDialog::initHead()
{
    // 加载图片
    QPixmap originalPixmap(":/icon/icon/Chat.png");
    //设置图片自动缩放
    originalPixmap = originalPixmap.scaled(ui->label_head->size(),
                                           Qt::KeepAspectRatio,
                                           Qt::SmoothTransformation);
    // 创建一个和原始图片大小相同的QPixmap，用于绘制圆角
    QPixmap roundedPixmap(originalPixmap.size());
    // 用透明色填充
    roundedPixmap.fill(Qt::transparent);
    QPainter painter(&roundedPixmap);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
    //使用QPaintertPath设置圆角
    QPainterPath path;
    path.addRoundedRect(originalPixmap.rect(), 10, 10);
    painter.setClipPath(path);
    // 将原始图片绘制到rouundedPixmap上
    painter.drawPixmap(0, 0, originalPixmap);
    // 设置绘制好的圆角图片到QLabel上
    ui->label_head->setPixmap(roundedPixmap);
}
// 登录逻辑
void LoginDialog::on_btn_login_clicked()
{
    if (!CheckEmailValid()) {
        QMessageBox::critical(this, "错误", "邮箱错误");
        return;
    }
    if (!CheckPassWordValid()) {
        QMessageBox::critical(this, "错误", "密码格式错误");
        return;
    }
    setBtnEnabled(false);
    QString email = ui->login_edt_email->text();
    QString pwd = ui->login_edt_password->text();
    QJsonObject root;
    root["email"] = email;
    root["password"] = QString(
        QCryptographicHash::hash(pwd.toUtf8(), QCryptographicHash::Sha1).toHex());
    // 发送请求
    HttpManager::GetInstance()->PostHttpReq(QUrl(gate_url_prefix + "/user_login"),
                                            root,
                                            ReqId::ID_LOGIN_USER,
                                            Modules::LOGINDMOD);
}

void LoginDialog::slot_login_finished(ReqId id, QString res, ErrorCode ec)
{
    setBtnEnabled(true);
    if (ec) {
        QMessageBox::critical(this, "错误", "参数错误");
        return;
    }
    QJsonParseError error;
    QJsonDocument jsonDocu = QJsonDocument::fromJson(res.toUtf8(), &error);
    if (error.error != QJsonParseError::NoError) {
        qDebug() << "json解析错误\n";
        QMessageBox::critical(this, "错误", "参数错误");
        return;
    }
    QJsonObject jsonObject = jsonDocu.object();

    _handles[id](jsonObject);
}

void LoginDialog::slot_login_failed(int err)
{
    setBtnEnabled(true);
    QString result = QString("登录失败， error is %1.").arg(err);
    QMessageBox::critical(this, "错误", result);
}

void LoginDialog::slot_tcp_con_finish(bool success)
{
    setBtnEnabled(true);
    if (success) {
        qDebug() << "聊天服务连接成功，正在登录...";
        QJsonObject jsonObj;
        jsonObj["uid"] = _uid;
        jsonObj["token"] = _token;
        QJsonDocument doc(jsonObj);
        QByteArray jsonData = doc.toJson(QJsonDocument::Compact);
        // 发送tcp请求给chat server
        emit TcpMgr::GetInstance()->sig_send_data(ReqId::ID_CHAT_LOGIN, jsonData);
    } else {
        qDebug() << "网络异常";
    }
}

bool LoginDialog::CheckEmailValid()
{
    //验证邮箱格式
    QString email = ui->login_edt_email->text();
    QRegularExpression regex(R"(^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$)");
    bool match = regex.match(email).hasMatch();
    if (!match) {
        return false;
    }
    return true;
}

bool LoginDialog::CheckPassWordValid()
{
    QString pass = ui->login_edt_password->text();
    if (pass.length() < 6 || pass.length() > 15) {
        return false;
    }
    // 创建一个正则表达式
    QRegularExpression regExp("^[a-zA-Z0-9!@#$%^&*]{6,15}$");
    bool match = regExp.match(pass).hasMatch();
    if (!match) {
        return false;
    }
    return true;
}

void LoginDialog::setBtnEnabled(bool enabled)
{
    ui->btn_froget->setEnabled(enabled);
    ui->btn_signup->setEnabled(enabled);
    ui->btn_login->setEnabled(enabled);
}

void LoginDialog::initHttpHandlers()
{
    _handles.insert(ReqId::ID_LOGIN_USER, [this](QJsonObject jsonObj) {
        int err = jsonObj["error"].toInt();
        if (err != ErrorCode::SUCCESS) {
            QMessageBox::critical(this, "错误", "参数错误");
            return;
        }
        auto email = jsonObj["email"].toString();
        // 发送信号通知tcpMgr创建长连接
        ServerInfo si;
        si.uid = jsonObj["uid"].toInt();
        si.Host = jsonObj["host"].toString();
        si.Port = jsonObj["port"].toString();
        si.Token = jsonObj["token"].toString();
        _uid = si.uid;
        _token = si.Token;
        qDebug() << "email is " << email << " uid is " << si.uid << " host is " << si.Host
                 << " Port is " << si.Port << " Token is " << si.Token;
        // 连接聊天服务器
        emit sig_connect_tcp(si);
        qDebug() << "登录成功";
    });
}
